<template>
  <view
    class="chatBottom"
    :style="{ height: chatBottomHeight(), bottom: chatBottom() }"
  >
    <view class="chatBottom-box" :style="{ height: chatBoxHeight() }">
      <image
        class="chatBottom-box-audio"
        src="@/pagesA/static/images/chat/chat_audio.png"
        @tap="audioClick"
      >
      </image>
      <view class="chatBottom-box-audioClick" @tap="audioClick"></view>
      <view
        v-if="showAudio"
        class="chatBottom-box-recordBg"
        @longpress="longpressRecord"
        @touchstart="touchStart"
        @touchmove="touchMove"
        @touchend="endRecord"
        :style="{ background: recordBgColor() }"
      >
        {{ recordText() }}
      </view>
      <view
        v-else
        class="chatBottom-box-inputBg"
        :style="{ height: `${inputBgHeight()}rpx`, width: inputBgWidth() }"
      >
        <textarea
          ref="textareaRef"
          class="input-box"
          :style="{ height: `${inputBgHeight()}rpx`, width: inputBgWidth() }"
          v-model="inputText"
          placeholder="输入内容..."
          autoheight
          :focus="textareaFocus"
          :showConfirmBar="false"
          :adjust-position="false"
          border="none"
          :maxlength="maxNum"
          confirmType="return"
          disable-default-padding="true"
          @linechange="linechange"
          @focus="focus"
          @blur="blur"
        ></textarea>
        <!-- :cursor-spacing="20" -->
      </view>

      <kk-button
        class="chatBottom-box-send"
        v-if="isCanSendText()"
        text="发送"
        @tap="sendMsg"
      />
      <image
        v-else
        class="chatBottom-box-add"
        src="@/pagesA/static/images/chat/chat_add.png"
        @tap="addClick"
      ></image>
      <view
        v-if="!isCanSendText()"
        class="chatBottom-box-addClick"
        @tap="addClick"
      ></view>
    </view>
    <view v-if="showOther" class="chatBottom-other">
      <kk-line class="line"></kk-line>
      <up-grid :border="false" col="4">
        <up-grid-item
          v-for="(item, index) in otherList"
          :key="index"
          @tap="otherItemClick(item)"
        >
          <view class="item">
            <image class="item-icon" :src="item.icon"></image>
            <view class="item-text">
              {{ item.name }}
            </view>
          </view>
        </up-grid-item>
      </up-grid>
    </view>
    <RecordStatus
      ref="recordStatusRef"
      v-if="recordStatus > 0"
      :recordStatus="recordStatus"
      :time="recordTime"
      @audioIsToShort="audioIsToShort"
      @uploadAudio="uploadAudio"
      @audioIsNotPermission="audioIsNotPermission"
    />
  </view>
</template>

<script lang="ts" setup>
import { onMounted, ref, nextTick } from "vue";
import RecordStatus from "./recordStatus.vue";

import chat_photo from "@/pagesA/static/images/chat/chat_photo.png";
import chat_camera from "@/pagesA/static/images/chat/chat_camera.png";
import chat_ai from "@/pagesA/static/images/chat/chat_ai.png";
import chat_exam from "@/pagesA/static/images/chat/chat_exam.png";
import kkToast from "@/utils/kkToast";

import { getUserInfo } from "@/utils/storageUtil";
import * as KKAswerApi from "@/api/answer";

const props = defineProps({
  topInputFoucs: {
    type: Boolean,
    default: false,
  },
});

const inputText = ref("");
const maxHeight = 220;
const minHeight = 70;
const otherHeight = 228;
const showOther = ref(false);

const showAudio = ref(false);
const recordStatus = ref(0); //0：按住 说话 1 松开发送 2 松开手指，取消发送 3说话时间太短

const textAreaHeight = ref(minHeight);
const textareaFocus = ref(false);
const textareaRef = ref();
const maxNum = 10000;

const otherList = ref([
  {
    name: "相册",
    icon: chat_photo,
    type: "album",
  },
  {
    name: "拍摄",
    icon: chat_camera,
    type: "camera",
  },
  {
    name: "AI回复",
    icon: chat_ai,
    type: "ai",
  },
  {
    name: "推送试题",
    icon: chat_exam,
    type: "exam",
  },
]);

// 是否能发送文本
const isCanSendText = () => {
  return inputText.value && !showAudio.value;
};

const chatBottomHeight = () => {
  return `calc(${chatBoxHeight()} + ${
    showOther.value ? otherHeight : 0
  }rpx + ${keywordHeightRpx()}rpx + env(safe-area-inset-bottom)) +`;
};

const chatBottom = () => {
  return `calc(0 + ${keywordHeightRpx()}rpx)`;
};

const chatBoxHeight = () => {
  return `calc(${inputBgHeight() + 30}rpx)`;
};

const keywordHeightRpx = () => {
  const heightRpx = keybordHeight.value / (uni.upx2px(100) / 100);
  return heightRpx;
};

const inputBgWidth = () => {
  if (isCanSendText()) {
    return `calc(100vw - 200rpx - 48rpx)`;
  } else {
    return `calc(100vw - 200rpx)`;
  }
};

const inputBgHeight = () => {
  if (showAudio.value) {
    return minHeight;
  }
  return textAreaHeight.value >= maxHeight ? maxHeight : textAreaHeight.value;
};

const getBottomHeight = () => {
  return (
    inputBgHeight() +
    30 +
    (showOther.value ? otherHeight : 0) +
    keywordHeightRpx()
  );
};

const linechange = (e: any) => {
  // const heightRpx = e.detail.height / (uni.upx2px(100) / 100);
  // if (e.detail.lineCount === 1) {
  //   line1Height.value = heightRpx;
  // }
  // if (!line1Height.value) {
  //   line1Height.value = 38;
  // }
  // if (heightRpx + line1Height.value > minHeight) {
  //   textAreaHeight.value = heightRpx + line1Height.value;
  // }
  // if (e.detail.lineCount === 1) {
  //   textAreaHeight.value = minHeight;
  // }
  let heightRpx = e.detail.heightRpx
    ? e.detail.heightRpx
    : e.detail.height / (uni.upx2px(100) / 100);
  if (heightRpx) {
    if (heightRpx < 38) {
      heightRpx = 38;
    }
  } else {
    heightRpx = 38;
  }
  textAreaHeight.value = heightRpx + 32;
  emit("bottomHeightChange", getBottomHeight());
  if (!inputText.value) {
    isAiReplay.value = false;
  }
};

const focus = (e: any) => {
  textareaFocus.value = true;
  showAudio.value = false;
  if (showOther.value) {
    showOther.value = false;
    emit("bottomHeightChange", getBottomHeight());
  }
  emit("scrollToBottom");
};

const blur = () => {
  textareaFocus.value = false;
  if (!isClickAddBtn.value) {
    showOther.value = false;
  }
  showAudio.value = false;
};

//录音按钮点击
const audioClick = () => {
  if (showAudio.value) {
    showAudio.value = false;
    textareaFocus.value = true;
  } else {
    showAudio.value = true;
    textareaFocus.value = false;
  }
  showOther.value = false;
  emit("bottomHeightChange", getBottomHeight());
};
const isClickAddBtn = ref(false);
// 添加按钮点击
const addClick = () => {
  isClickAddBtn.value = true;
  timer.value = setTimeout(() => {
    isClickAddBtn.value = false;
  }, 500);
  if (showOther.value) {
    showOther.value = false;
    emit("bottomHeightChange", getBottomHeight());
    textareaFocus.value = true;
  } else {
    showOther.value = true;
    textareaFocus.value = false;
    emit("bottomHeightChange", getBottomHeight());
    emit("scrollToBottom");
  }
  showAudio.value = false;
};

// 发送消息
const sendMsg = () => {
  inputText.value = inputText.value.slice(
    0,
    inputText.value.length > maxNum ? maxNum : inputText.value.length
  );
  emit("sendMsg", inputText.value, isAiReplay.value);
  inputText.value = "";
  isAiReplay.value = false;
};

const recordText = () => {
  if (recordStatus.value === 0 || recordStatus.value === 3) {
    return "按住 说话";
  } else if (recordStatus.value === 1) {
    return "松开发送";
  } else if (recordStatus.value === 2) {
    return "松开手指，取消发送";
  }
};

// 录音背景颜色
const recordBgColor = () => {
  if (recordStatus.value === 0 || recordStatus.value === 3) {
    return "#fff";
  } else {
    return "#f2f2f2";
  }
};
//长按录音
const longpressRecord = () => {
  recordStatus.value = 1;
  recordTime.value = 0;
  startTimer();
};

const isTiming = ref(false);
const timer = ref(null);
const recordTime = ref(0);
const recordStatusRef = ref();
const startTimer = () => {
  isTiming.value = true;
  timer.value = setInterval(() => {
    recordTime.value++;
  }, 1000);
};

const stopTimer = () => {
  isTiming.value = false;
  if (timer.value) {
    clearInterval(timer.value);
  }
};

const startTouchData = ref({ clientX: 0, clientY: 0 });

const touchStart = (e: any) => {
  // 无论你是否绑定longpress，只要手指触摸这个view，就触发start
  // 这里我们需要记录此时的坐标
  startTouchData.value.clientX = e.changedTouches[0].clientX; //手指按下时的X坐标
  startTouchData.value.clientY = e.changedTouches[0].clientY; //手指按下时的Y坐标
};

const touchMove = (e: any) => {
  // 触摸后继续移动手指时，将触发这个事件
  // 这里我们根据每次移动的坐标变化判断是向上还是向下滑动
  let touchData = e.touches[0]; //滑动过程中，手指滑动的坐标信息 返回的是Objcet对象
  let moveY = touchData.clientY - startTouchData.value.clientY;
  if (moveY < -100) {
    // 取消录音
    recordStatus.value = 2;
  } else {
    //录音中
    recordStatus.value = 1;
  }
};

const endRecord = (e: any) => {
  stopTimer();
  if (recordStatus.value === 1) {
    if (recordStatusRef.value) {
      recordStatusRef.value.recStop();
    } else {
      recordStatus.value = 0;
    }
  } else if (recordStatus.value === 2) {
    recordStatus.value = 0;
  }
};

// 上传音频
const uploadAudio = (filePath: string, duration: number) => {
  recordStatus.value = 0;
  emit("uploadAudio", filePath, duration);
};

// 录音没有权限
const audioIsNotPermission = () => {
  console.log("没有录音权限");
  recordStatus.value = 0;
  stopTimer();
};

// 音频录制太短
const audioIsToShort = () => {
  recordStatus.value = 3;
  timer.value = setTimeout(() => {
    recordStatus.value = 0;
    stopTimer();
  }, 1500);
};
const otherItemClick = (item: any) => {
  if (item.type === "album") {
    uni.chooseMedia({
      count: 9,
      mediaType: ["image", "video"],
      sourceType: ["album"],
      success(res) {
        const tempFilePaths = [] as any;
        if (res.tempFiles && res.tempFiles.length > 0) {
          res.tempFiles.forEach((item) => {
            if (item.fileType === "image") {
              if (item.size <= 1024 * 1024 * 5) {
                // 大于5M的图片不发送
                tempFilePaths.push(item);
              } else {
                kkToast.showToast("请上传5MB以内的图片");
              }
            } else if (item.fileType === "video") {
              if (item.size <= 1024 * 1024 * 200) {
                // 大于200M的视频不发送
                tempFilePaths.push(item);
              } else {
                kkToast.showToast("请上传200MB以内的视频");
              }
            }
          });
          if (tempFilePaths.length > 0) {
            emit("sendImageAndVideo", tempFilePaths);
          }
        }
      },
    });
  } else if (item.type === "camera") {
    uni.chooseImage({
      count: 1, //
      sourceType: ["camera"], // 可选择来源是相机
      success: (res) => {
        const tempFilePaths = res.tempFiles;
        if (tempFilePaths && tempFilePaths.length > 0) {
          if (tempFilePaths[0].size <= 1024 * 1024 * 5) {
            // 大于5M的图片不发送
            emit("sendImageAndVideo", [
              { tempFilePath: tempFilePaths[0].path, fileType: "image" },
            ]);
          } else {
            kkToast.showToast("请上传5MB以内的图片");
          }
        }
      },
      fail: (err) => {},
    });
  } else if (item.type === "ai") {
    emit("bottomAiReplayTap");
  } else if (item.type === "exam") {
    emit("bottomPushExamTap");
  }
};

const isAiReplay = ref(false);
const addAiReplayContent = (content: string) => {
  inputText.value = (content || "").replace(/<p[^>]*>|<\/p[^>]*>/gi, "") || "";
  isAiReplay.value = true;
  showAudio.value = false;
  addAnswerCountReq();
};

const addAnswerCountReq = async () => {
  let adminId = getUserInfo().adminUserId || "";
  await KKAswerApi.addAiResponseCntProt({ adminId: adminId }).catch(() => {});
};

const keybordHeight = ref(0);
onMounted(() => {
  uni.onKeyboardHeightChange((res) => {
    console.log(res.height);
    if (props.topInputFoucs.value) {
      keybordHeight.value = 0;
    } else {
      keybordHeight.value = res.height;
    }
    emit("bottomHeightChange", getBottomHeight());
  });
});

const emit = defineEmits([
  "bottomHeightChange",
  "scrollToBottom",
  "sendMsg",
  "sendImageAndVideo",
  "uploadAudio",
  "bottomAiReplayTap",
  "bottomPushExamTap",
]);
defineExpose({ addAiReplayContent });
</script>

<style lang="scss" scoped>
.chatBottom {
  background: #f1f2f3;
  position: fixed;
  // bottom: 0;
  width: calc(100vw);
  z-index: 999;
  &-box {
    position: relative;
    background: #f7f7f7;
    display: flex;
    flex-direction: row;
    &-audio {
      margin-top: auto;
      margin-bottom: 24rpx;
      margin-left: 24rpx;
      width: 52rpx;
      height: 52rpx;
    }

    &-audioClick {
      position: absolute;
      bottom: 0px;
      margin-top: auto;
      margin-bottom: 0rpx;
      margin-left: 0rpx;
      width: 100rpx;
      height: 100rpx;
    }

    &-inputBg {
      margin-top: 15rpx;
      margin-left: 24rpx;
      margin-right: 24rpx;
      width: calc(100vw - 96rpx - 104rpx);
      background: #ffffff;
      border-radius: 16rpx;
      display: flex;
      flex-direction: column;
      .input-box {
        margin-top: 16rpx;
        margin-bottom: 16rpx;
        margin-left: 20rpx;
        padding-right: 24rpx;
        flex: 1;
        box-sizing: border-box;
      }
    }

    &-recordBg {
      margin-top: 15rpx;
      margin-left: 24rpx;
      margin-right: 24rpx;
      height: 70rpx;
      width: calc(100vw - 96rpx - 104rpx);
      background: #f2f2f2;
      background: #ffffff;

      border-radius: 16rpx;
      font-size: 28rpx;
      color: #999999;
      line-height: 70rpx;
      text-align: center;
    }

    &-add {
      margin-top: auto;
      margin-bottom: 24rpx;
      margin-right: 24rpx;
      width: 52rpx;
      height: 52rpx;
    }
    &-addClick {
      position: absolute;
      bottom: 0px;
      right: 0px;
      margin-top: auto;
      margin-bottom: 0rpx;
      margin-left: 0rpx;
      width: 100rpx;
      height: 100rpx;
    }
    &-send {
      margin-top: auto;
      margin-bottom: 48rpx;
      margin-right: 24rpx;
      width: 100rpx;
      height: 30rpx;
    }
  }

  &-other {
    height: 228rpx;
    .line {
      background: rgba(0, 0, 0, 0.1);
    }
    .item {
      margin: 34rpx;
      display: flex;
      flex-direction: column;
      align-items: center;
      &-icon {
        width: 120rpx;
        height: 120rpx;
      }
      &-text {
        padding-top: 16rpx;
        font-size: 24rpx;
        color: #666666;
        line-height: 28rpx;
      }
    }
  }
}
</style>
